package com.bsoft.gol.hcs.specialist.dao;

import ctd.persistence.annotation.DAOMethod;
import ctd.persistence.annotation.DAOParam;
import ctd.persistence.support.hibernate.HibernateSupportDelegateDAO;
import ctd.persistence.support.hibernate.template.AbstractHibernateStatelessResultAction;
import ctd.persistence.support.hibernate.template.HibernateSessionTemplate;
import ctd.persistence.support.hibernate.template.HibernateStatelessResultAction;
import ctd.util.converter.ConversionUtils;
import com.bsoft.gol.hcs.enumcase.FollowTypeEnum;
import org.hibernate.Query;
import org.hibernate.StatelessSession;
import org.hibernate.criterion.CriteriaSpecification;
import com.bsoft.gol.hcs.specialist.bean.request.GroupChronicRecordQo;
import com.bsoft.gol.hcs.specialist.bean.response.FactorData;
import com.bsoft.gol.hcs.specialist.bean.response.OperativeRecordResponse;
import com.bsoft.gol.hcs.specialist.entity.FusAnswerOperativeInfo;
import com.bsoft.gol.hcs.utils.CommonUtils;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * @author tongtp
 * @version v0.1
 * @className FusAnswerOperativeInfoDAO
 * @description
 * @create 2020-07-31 15:08
 **/
public abstract class FusAnswerOperativeInfoDAO extends HibernateSupportDelegateDAO<FusAnswerOperativeInfo> {

    /**
     * @param reportId
     * @throws
     * @description: 根据表单答案唯一记录id查询
     * @return: specialist.entity.FusAnswerOperativeInfo
     * @author: tongtp
     * @date: 2020/8/4 17:57
     */
    @DAOMethod(sql = " from FusAnswerOperativeInfo where reportId = :reportId")
    public abstract FusAnswerOperativeInfo getByReportId(@DAOParam("reportId") String reportId);

    /**
     * 根据病人id和病种id获取手术信息
     *
     * @param qo
     * @return
     */
    public List<OperativeRecordResponse> queryAnswerOperativeInfoList(GroupChronicRecordQo qo) {
        HibernateStatelessResultAction<List<OperativeRecordResponse>> action = new AbstractHibernateStatelessResultAction<List<OperativeRecordResponse>>() {
            @Override
            public void execute(StatelessSession ss) throws Exception {
                StringBuilder sqlBuilder = new StringBuilder();
                sqlBuilder.append("SELECT operative_code as operativeCode,operative_record_id as operativeRecordId,operative_name as operativeName,operative_time as operativeTime from fus_answer_operative_info WHERE patient_id =:patientId and disease_type_id =:diseaseTypeId ");
                sqlBuilder.append(" and create_time >=:beginTime and create_time <=:endTime");
                Query query = ss.createSQLQuery(sqlBuilder.toString());
                query.setParameter("patientId", qo.getPatientId());
                query.setParameter("diseaseTypeId", qo.getDiseaseTypeId());
                if (CommonUtils.isNotEmpty(qo.getBeginTime())){
                    query.setParameter("beginTime", qo.getBeginTime()+" 00:00:00");
                }
                if (CommonUtils.isNotEmpty(qo.getBeginTime())){
                    query.setParameter("endTime", qo.getEndTime()+" 23:59:59");
                }
                query.setResultTransformer(CriteriaSpecification.ALIAS_TO_ENTITY_MAP);
                List<Map> list = query.list();
                List<OperativeRecordResponse> voList = new ArrayList<>();
                if (CommonUtils.isNotEmpty(list)) {
                    for (Map map : list) {
                        voList.add(ConversionUtils.convert(map, OperativeRecordResponse.class));
                    }
                } else {
                    voList = new ArrayList<>();
                }
                setResult(voList);
            }
        };
        HibernateSessionTemplate.instance().execute(action);
        return action.getResult();
    }

    /**
     * 根据病人id和病种id和手术名称获取手术时间
     *
     * @param qo
     * @return
     */
    public List<OperativeRecordResponse.OperativeTimeList> queryAnswerOperativeTimeList(GroupChronicRecordQo qo,String operativeName) {
        HibernateStatelessResultAction<List<OperativeRecordResponse.OperativeTimeList>> action = new AbstractHibernateStatelessResultAction<List<OperativeRecordResponse.OperativeTimeList>>() {
            @Override
            public void execute(StatelessSession ss) throws Exception {
                StringBuilder sqlBuilder = new StringBuilder();
                sqlBuilder.append("SELECT operative_record_id as operativeRecordId,operative_name as operativeName,operative_time as operativeTime from fus_answer_operative_info WHERE patient_id =:patientId and disease_type_id =:diseaseTypeId and operative_name =:operativeName ");
                sqlBuilder.append(" and create_time >=:beginTime and create_time <=:endTime order by create_time ");
                Query query = ss.createSQLQuery(sqlBuilder.toString());
                query.setParameter("patientId", qo.getPatientId());
                query.setParameter("diseaseTypeId", qo.getDiseaseTypeId());
                query.setParameter("operativeName", operativeName);
                if (CommonUtils.isNotEmpty(qo.getBeginTime())){
                    query.setParameter("beginTime", qo.getBeginTime()+" 00:00:00");
                }
                if (CommonUtils.isNotEmpty(qo.getBeginTime())){
                    query.setParameter("endTime", qo.getEndTime()+" 23:59:59");
                }
                query.setResultTransformer(CriteriaSpecification.ALIAS_TO_ENTITY_MAP);
                List<Map> list = query.list();
                List<OperativeRecordResponse.OperativeTimeList> voList = new ArrayList<>();
                if (CommonUtils.isNotEmpty(list)) {
                    for (Map map : list) {
                        voList.add(ConversionUtils.convert(map, OperativeRecordResponse.OperativeTimeList.class));
                    }
                } else {
                    voList = new ArrayList<>();
                }
                setResult(voList);
            }
        };
        HibernateSessionTemplate.instance().execute(action);
        return action.getResult();
    }

    /**
     * 根据用户和病种查询ReportId
     *
     * @param diseaseTypeId
     * @param patientId
     * @param patientMedicalCardType
     * @param patientMedicalCardNumber
     * @param cardType
     * @param cardNumber
     * @return java.util.List<java.lang.String>
     * @throws
     * @author tongtp
     * @date 2021/12/29 13:41
     */
    public List<String> queryReportId(Long diseaseTypeId, String patientId,
                                      Integer patientMedicalCardType, String patientMedicalCardNumber,
                                      String cardType, String cardNumber) {
        HibernateStatelessResultAction<List<String>> action =
                new AbstractHibernateStatelessResultAction<List<String>>() {
                    @Override
                    public void execute(StatelessSession ss) throws Exception {
                        StringBuilder sqlBuilder = new StringBuilder();
                        sqlBuilder.append("select report_id from fus_answer_operative_info" +
                                "  where disease_type_id = :diseaseTypeId ");
                        sqlBuilder.append(" and ( ");
                        if (CommonUtils.isNotNull(patientId)) {
                            sqlBuilder.append(" patient_id = :patientId ");
                        }
                        if (CommonUtils.isNotNull(patientMedicalCardType) && CommonUtils.isNotNull(patientMedicalCardNumber)) {
                            sqlBuilder.append("  or (patient_medical_card_type = :patientMedicalCardType and" +
                                    " patient_medical_card_number = :patientMedicalCardNumber) ");
                        }
                        if (CommonUtils.isNotNull(cardType) && CommonUtils.isNotNull(cardNumber)) {
                            sqlBuilder.append("  or (card_type = :cardType and" +
                                    " card_number = :cardNumber) ");
                        }
                        sqlBuilder.append(" ) ");
                        Query query = ss.createSQLQuery(sqlBuilder.toString());
                        query.setParameter("diseaseTypeId", diseaseTypeId);
                        if (CommonUtils.isNotNull(patientId)) {
                            query.setParameter("patientId", patientId);
                        }
                        if (CommonUtils.isNotNull(patientMedicalCardType) && CommonUtils.isNotNull(patientMedicalCardNumber)) {
                            query.setParameter("patientMedicalCardType", patientMedicalCardType);
                            query.setParameter("patientMedicalCardNumber", patientMedicalCardNumber);
                        }
                        if (CommonUtils.isNotNull(cardType) && CommonUtils.isNotNull(cardNumber)) {
                            query.setParameter("cardType", cardType);
                            query.setParameter("cardNumber", cardNumber);
                        }
                        List list = query.list();
                        List<String> voList;
                        if (CommonUtils.isNotEmpty(list)) {
                            voList = list;
                        } else {
                            voList = new ArrayList<>();
                        }
                        setResult(voList);
                    }
                };
        HibernateSessionTemplate.instance().execute(action);
        return action.getResult();
    }

    public List<FactorData> executeFactorForOperation(List<String> operateIdList, Date startTime, Date endTime, List<String> patientIdList,Byte isLoopExecute,Long routeDetailId, String followType) {
        HibernateStatelessResultAction<List<FactorData>> action = new AbstractHibernateStatelessResultAction<List<FactorData>>() {
            @Override
            public void execute(StatelessSession ss) throws Exception {
                StringBuilder sqlBuilder = new StringBuilder();
                sqlBuilder.append("select patientId,operationRecordId,operationCode,operationName ,operationEndTime,dataSource from (");
                sqlBuilder.append("SELECT patient_id as patientId,operative_record_id operationRecordId,operative_code operationCode,");
                sqlBuilder.append( "operative_name operationName,operative_time as  operationEndTime,'2' as dataSource FROM `fus_answer_operative_info` ");
                sqlBuilder.append(" WHERE operative_code in (:operationCode)  ");
                if (null != endTime) {
                    sqlBuilder.append("  and  operative_time <:endTime ");
                }
                if (null != startTime) {
                    sqlBuilder.append(" and operative_time> :startTime");
                }
                if (CommonUtils.isNotEmpty(patientIdList)) {
                    sqlBuilder.append(" and patient_id in (:patientIdList)");
                }
                sqlBuilder.append(") AS  m ");
                //循环执行机制 0 不执行 1 执行
                if (FollowTypeEnum.FUS_SPECIALIST.getType().equals(followType) && null != isLoopExecute && isLoopExecute == 1) {
                    sqlBuilder.append(" LEFT JOIN fus_factor_data_record f  ON f.patient_id = m.patientId   AND f.route_detail_id = :routeDetailId AND f.operation_record_id = m.operationRecordId WHERE f.id IS NULL  ");
                }
                Query query = ss.createSQLQuery(sqlBuilder.toString());
                query.setParameterList("operationCode", operateIdList);
                if (null != endTime) {
                    query.setParameter("endTime", endTime);
                }
                if (null != startTime) {
                    query.setParameter("startTime", startTime);
                }
                if (CommonUtils.isNotEmpty(patientIdList)) {
                    query.setParameterList("patientIdList", patientIdList);
                }
                if (FollowTypeEnum.FUS_SPECIALIST.getType().equals(followType) && null != isLoopExecute && isLoopExecute == 1) {
                    query.setParameter("routeDetailId", routeDetailId);
                }
                query.setResultTransformer(CriteriaSpecification.ALIAS_TO_ENTITY_MAP);
                List<Map> list = query.list();
                List<FactorData> voList = new ArrayList<>();
                if (CommonUtils.isNotEmpty(list)) {
                    for (Map map : list) {
                        voList.add(ConversionUtils.convert(map, FactorData.class));
                    }
                } else {
                    voList = new ArrayList<>();
                }
                setResult(voList);
            }
        };
        HibernateSessionTemplate.instance().execute(action);
        return action.getResult();
    }
}
